using System;
using System.Data;
using DreamStore.WebShop.Models;
using Orchard.Autoroute.Models;
using Orchard.Comments.Models;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Common.Fields;
using Orchard.Core.Common.Models;
using Orchard.Core.Containers.Models;
using Orchard.Core.Contents.Extensions;
using Orchard.Core.Navigation.Models;
using Orchard.Core.Title.Models;
using Orchard.Data.Migration;
using Orchard.Tags.Models;
using Orchard.Users.Models;
using Orchard.Widgets.Models;
using Orchard.MediaPicker;

namespace DreamStore.WebShop
{
    public class Migrations : DataMigrationImpl
    {

        public int Create()
        {
            // Creating table ProductRecord
            SchemaBuilder.CreateTable("ProductRecord", table => table
                .ContentPartRecord()
                .Column("Price", DbType.Decimal)
                .Column("Sku", DbType.String, column => column.WithLength(50))
            );
            return 1;
        }

        public int UpdateFrom1()
        {
            //Making the ProductPart ContentType Attachable
            ContentDefinitionManager.AlterPartDefinition(typeof(ProductPart).Name,
                part => part
                    .WithField("Image", f => f.OfType("MediaPickerField"))
                    .Attachable());
            return 2;
        }

        public int UpdateFrom2()
        {
            //Creating a ProductCatalog Content Type
            ContentDefinitionManager.AlterTypeDefinition("ProductCatalog", type => type
                .WithPart(typeof(CommonPart).Name)
                .WithPart(typeof(ContainerPart).Name)
                .WithPart(typeof(MenuPart).Name)
                .WithPart(typeof(AdminMenuPart).Name)
                .WithPart(typeof(TitlePart).Name)
                .WithPart(typeof(AutoroutePart).Name, builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                    .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
                    .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'the-title'}]")
                    .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                .Creatable()
                .Draftable()
                );
            return 3;
        }

        public int UpdateFrom3()
        {
            //Creating a ShoppingCart Widget
            ContentDefinitionManager.AlterTypeDefinition("ShoppingCartWidget",
                type => type
                .WithPart(typeof(ShoppingCartWidgetPart).Name)
                .WithPart(typeof(WidgetPart).Name)
                .WithPart(typeof(CommonPart).Name)
                .WithSetting("Stereotype", "Widget"));
            return 4;
        }

        public int UpdateFrom4()
        {
            //Creating the CustomerRecord DB table
            SchemaBuilder.CreateTable("CustomerRecord", t => t
                .ContentPartRecord()
                .Column<string>("Title", c => c.WithLength(10))
                .Column<string>("FirstName", c => c.WithLength(50))
                .Column<string>("LastName", c => c.WithLength(50))
                .Column<DateTime>("CreatedAt", c => c.NotNull()));

            //Creating the AddressRecord DB table
            SchemaBuilder.CreateTable("AddressRecord", t => t
                .ContentPartRecord()
                .Column<int>("CustomerId")
                .Column<string>("Type", c => c.WithLength(50)));

            //Creating foreign key record between AddressRecord and CustomerRecord
            SchemaBuilder.CreateForeignKey("Address_Customer",
                "AddressRecord", new[] { "CustomerId" },
                "CustomerRecord", new[] { "Id" });

            //Making the CustomerPart ContentPart attachable
            ContentDefinitionManager.AlterPartDefinition(typeof(CustomerPart).Name, p => p.Attachable());

            //Creating Customer ContentType
            ContentDefinitionManager.AlterTypeDefinition("Customer", t => t
                .WithPart(typeof(CustomerPart).Name)
                .WithPart(typeof(UserPart).Name));

            //Adding text fields to Address ContentPart and making it not Attachable
            ContentDefinitionManager.AlterPartDefinition(typeof(AddressPart).Name, p => p
                .WithField("Name", f => f.OfType(typeof(TextField).Name))
                .WithField("AddressLine1", f => f.OfType(typeof(TextField).Name))
                .WithField("AddressLine2", f => f.OfType(typeof(TextField).Name))
                .WithField("Zipcode", f => f.OfType(typeof(TextField).Name))
                .WithField("City", f => f.OfType(typeof(TextField).Name))
                .WithField("Country", f => f.OfType(typeof(TextField).Name))
                .Attachable(false));

            //Creating Adress ContentType
            ContentDefinitionManager.AlterTypeDefinition("Address", t => t
                .WithPart(typeof(AddressPart).Name));

            return 5;
        }

        public int UpdateFrom5()
        {
            //Creating OrderRecord DB table
            SchemaBuilder.CreateTable("OrderRecord", t => t
                .Column<int>("Id", c => c.PrimaryKey().Identity())
                .Column<int>("CustomerId", c => c.NotNull())
                .Column<DateTime>("CreatedAt", c => c.NotNull())
                .Column<decimal>("SubTotal", c => c.NotNull())
                .Column<decimal>("Vat", c => c.NotNull())
                .Column<string>("Status", c => c.WithLength(50).NotNull())
                .Column<string>("PaymentServiceProviderResponse", c => c.WithLength(null))
                .Column<string>("PaymentReference", c => c.WithLength(50))
                .Column<DateTime>("PaidAt", c => c.Nullable())
                .Column<DateTime>("CompletedAt", c => c.Nullable())
                .Column<DateTime>("CancelledAt", c => c.Nullable())
                );

            //Creating OrderDetailRecord DB table
            SchemaBuilder.CreateTable("OrderDetailRecord", t => t
                .Column<int>("Id", c => c.PrimaryKey().Identity())
                .Column<int>("OrderRecord_Id", c => c.NotNull())
                .Column<int>("ProductId", c => c.NotNull())
                .Column<int>("Quantity", c => c.NotNull())
                .Column<decimal>("UnitPrice", c => c.NotNull())
                .Column<decimal>("VatRate", c => c.NotNull())
                );

            //Creating foreign key record between OrderRecord and CustomerRecord
            SchemaBuilder.CreateForeignKey("Order_Customer",
                "OrderRecord", new[] { "CustomerId" },
                "CustomerRecord", new[] { "Id" });

            //Creating foreign key record between OrderDetailRecord and OrderRecord
            SchemaBuilder.CreateForeignKey("OrderDetail_Order",
                "OrderDetailRecord", new[] { "OrderRecord_Id" },
                "OrderRecord", new[] { "Id" });

            //Creating foreign key record between OrderDetailRecord and ProductRecord
            SchemaBuilder.CreateForeignKey("OrderDetail_Product",
                "OrderDetailRecord", new[] { "ProductId" },
                "ProductRecord", new[] { "Id" });

            return 6;
        }

        public int UpdateFrom6()
        {
            SchemaBuilder.CreateTable("CustomerDiscountsPartRecord", t => t
                .ContentPartRecord());

            SchemaBuilder.CreateTable("CustomerDiscountProgramPartRecord", t => t
                .ContentPartRecord()
                .Column<string>("Name")
                .Column<double>("Discount"));

            SchemaBuilder.CreateTable("ContentCustomerDiscountProgramsRecord", t => t
                .Column<int>("Id", column => column.PrimaryKey().Identity())
                .Column<int>("CustomerDiscountsPartRecord_Id")
                .Column<int>("CustomerDiscountProgramPartRecord_Id"));

            //Creating the CustomerDiscountProgram content type
            ContentDefinitionManager.AlterTypeDefinition("CustomerDiscount", type => type
                .WithPart(typeof(CustomerDiscountProgramPart).Name)
                .Creatable());

            //Making the CustomerDiscountsPart attacable
            ContentDefinitionManager.AlterPartDefinition("CustomerDiscountsPart", p => p.Attachable());

            //Adding the CustomerDiscountsPart to Customer content type
            ContentDefinitionManager.AlterTypeDefinition("Customer", t => t
                .WithPart(typeof(CustomerDiscountsPart).Name));

            return 7;
        }

        public int UpdateFrom7()
        {
            // Creating 4 different product types (content types)

            ContentDefinitionManager.AlterTypeDefinition("Book", t => t
                .WithPart(typeof(CommonPart).Name)
                .WithPart(typeof(AutoroutePart).Name, builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                    .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
                    .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'the-title'}]")
                    .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                .WithPart(typeof(BodyPart).Name)
                .WithPart(typeof(CommentsPart).Name)
                .WithPart(typeof(ContainablePart).Name)
                .WithPart(typeof(ProductPart).Name)
                .WithPart(typeof(TagsPart).Name)
                .WithPart(typeof(TitlePart).Name)
                .Creatable()
                .Draftable());

            ContentDefinitionManager.AlterTypeDefinition("Sedative", t => t
                .WithPart(typeof(CommonPart).Name)
                .WithPart(typeof(AutoroutePart).Name, builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                    .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
                    .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'the-title'}]")
                    .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                .WithPart(typeof(BodyPart).Name)
                .WithPart(typeof(CommentsPart).Name)
                .WithPart(typeof(ContainablePart).Name)
                .WithPart(typeof(ProductPart).Name)
                .WithPart(typeof(TagsPart).Name)
                .WithPart(typeof(TitlePart).Name)
                .Creatable()
                .Draftable());

            ContentDefinitionManager.AlterTypeDefinition("DreamMachine", t => t
                .WithPart(typeof(CommonPart).Name)
                .WithPart(typeof(AutoroutePart).Name, builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                    .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
                    .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'the-title'}]")
                    .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                .WithPart(typeof(BodyPart).Name)
                .WithPart(typeof(CommentsPart).Name)
                .WithPart(typeof(ContainablePart).Name)
                .WithPart(typeof(ProductPart).Name)
                .WithPart(typeof(TagsPart).Name)
                .WithPart(typeof(TitlePart).Name)
                .Creatable()
                .Draftable());

            ContentDefinitionManager.AlterTypeDefinition("Dream", t => t
                .WithPart(typeof(CommonPart).Name)
                .WithPart(typeof(AutoroutePart).Name, builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                    .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
                    .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'the-title'}]")
                    .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                .WithPart(typeof(BodyPart).Name)
                .WithPart(typeof(CommentsPart).Name)
                .WithPart(typeof(ContainablePart).Name)
                .WithPart(typeof(ProductPart).Name)
                .WithPart(typeof(TagsPart).Name)
                .WithPart(typeof(TitlePart).Name)
                .Creatable()
                .Draftable());

            return 8;
        }

        public int UpdateFrom8()
        {
            //Creating the table for PayPal api settings
            SchemaBuilder.CreateTable("PayPalApiSettingsPartRecord", builder => builder
                .ContentPartRecord()
                .Column<string>("ApiDomain")
                .Column<string>("CgiDomain")
                .Column<string>("Username")
                .Column<string>("Password")
                .Column<string>("Signature"));
            return 9;
        }
    }
}